package org.sky.security.support;

import java.io.IOException;
import javax.annotation.PostConstruct;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.apache.logging.log4j.Logger;
import org.sky.util.LogUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.SecurityMetadataSource;
import org.springframework.security.access.intercept.AbstractSecurityInterceptor;
import org.springframework.security.access.intercept.InterceptorStatusToken;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.web.FilterInvocation;
import org.springframework.stereotype.Component;

/**
 * @author weifx
 * @Title: MySecurityFilter
 * @ProjectName springboot-platform
 * @Description: TODO{
 *  该过滤器的主要作用就是通过spring著名的IoC生成securityMetadataSource。
 *  securityMetadataSource相当于本包中自定义的MyInvocationSecurityMetadataSourceService。
 *  该MyInvocationSecurityMetadataSourceService的作用提从数据库提取权限和资源，装配到HashMap中，
 *  供Spring Security使用，用于权限校验。
 * }
 * @date 2019/3/1 14:19
 * @Version 1.0
 */
@Component
public class CustomSecurityFilter extends AbstractSecurityInterceptor
        implements Filter{
    Logger log = LogUtils.getLogger(CustomSecurityFilter.class);
    @Autowired
    private CustomInvocationSecurityMetadataSourceService  mySecurityMetadataSource;
    @Autowired
    private CustomAccessDecisionManager myAccessDecisionManager;
    @Autowired
    private AuthenticationManager authenticationManager;

    @PostConstruct
    public void init(){
        log.info("web容器初始化,调用一次init()");
        super.setAuthenticationManager(authenticationManager);
        super.setAccessDecisionManager(myAccessDecisionManager);
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException{
        FilterInvocation fi = new FilterInvocation( request, response, chain );
        invoke(fi);
    }
    public Class<? extends Object> getSecureObjectClass(){
        return FilterInvocation.class;
    }
    public void invoke(FilterInvocation fi) throws IOException, ServletException{
        log.info("对{}进行过滤",fi.getRequest().getRequestURI());
        InterceptorStatusToken  token = super.beforeInvocation(fi);
        try{
            fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
        }finally{
            super.afterInvocation(token, null);
        }
    }
    @Override
    public SecurityMetadataSource obtainSecurityMetadataSource(){
        log.debug("获取Security源数据...");
        return this.mySecurityMetadataSource;
    }
    public void destroy(){
        log.debug("过滤器销毁...");
    }
    public void init(FilterConfig filterconfig) throws ServletException{
        log.debug("过滤器初始化...");
    }
}
